package com.hongawen.shiro.realm;

import com.hongawen.shiro.entity.*;
import com.hongawen.shiro.service.*;
import com.mysql.cj.util.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author hongawen
 * @version 1.0.0
 * @date 2021年12月14日 09:05
 */
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private IUserService userService;

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IRolePermissionService rolePermissionService;

    @Autowired
    private IPermissionService permissionService;


    /**
     * 用户认证方法
     *
     * @param authenticationToken .
     * @return .
     * @throws AuthenticationException .
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //从token中获取用户信息
        String userName = (String) authenticationToken.getPrincipal();
        User user = userService.lambdaQuery()
                .eq(User::getUsername, userName)
                .one();
        if (Objects.isNull(user) || StringUtils.isNullOrEmpty(user.getPassword())) {
            return null;
        }
        return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
    }

    /**
     * 授权校验方法
     *
     * @param principalCollection .
     * @return .
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User newUser = (User) principalCollection.getPrimaryPrincipal();
        User user = userService.lambdaQuery()
                .eq(User::getUsername, newUser.getUsername())
                .one();
        if(Objects.isNull(user)){
            return null;
        }
        List<UserRole> userRoles = userRoleService.lambdaQuery()
                .eq(UserRole::getUserId,user.getId())
                .list();
        List<Role> roles = roleService.lambdaQuery()
                .in(Role::getId,userRoles
                        .stream()
                        .map(UserRole::getRoleId)
                        .collect(Collectors.toList()))
                .list();
        List<RolePermission> rolePermissions = rolePermissionService.lambdaQuery()
                .in(RolePermission::getRoleId,roles
                        .stream()
                        .map(Role::getId)
                        .collect(Collectors.toList()))
                .list();
        List<Permission> permissions = permissionService.lambdaQuery()
                .in(Permission::getId,rolePermissions
                        .stream()
                        .map(RolePermission::getPermissionId)
                        .collect(Collectors.toList()))
                .list();

        //角色集合
        List<String> roleList = roles.stream().map(Role::getName).collect(Collectors.toList());
        //权限集合
        List<String> permissionList = permissions.stream().map(Permission::getName).collect(Collectors.toList());
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRoles(roleList);
        simpleAuthorizationInfo.addStringPermissions(permissionList);
        return simpleAuthorizationInfo;
    }


}
